﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace RaytracerLib.MathLib.RootFinders
{
    public class BisectionRootFinder : BracketedRootFinder
    {
        public override double FindRoot(double a_a, double a_b, Func<double, double> a_func)
        {
            Debug.Assert(a_a < a_b);

            double ya = a_func(a_a);
            double yb = a_func(a_b);

            if (Math.Abs(ya) < AbsoluteError)
                return a_a;
            if (Math.Abs(yb) < AbsoluteError)
                return a_b;

            if (Math.Sign(ya) * Math.Sign(yb) > 0)
                return Double.PositiveInfinity;

            double x = 0;

            for (int i = 0; i < MaxIterations; i++)
            {
                x = (a_a + a_b) / 2;
                double y = a_func(x);

                if (Math.Abs(x) > AbsoluteError)
                {
                    if (Math.Abs(y / x) < AbsoluteError)
                        return x;
                }
                else if (Math.Abs(y) < AbsoluteError)
                    return x;

                if ((Math.Sign(ya) * Math.Sign(y)) < 0)
                {
                    a_b = x;
                    yb = y;
                }
                else
                {
                    a_a = x;
                    ya = y;
                }
            }

            return x;
        }
    }
}
